/* Copyright © Worklight Ltd. 2006-2011.  All rights reserved. */

package com.worklight.wlclient;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

import com.worklight.wlclient.api.WLAuthListener;
import com.worklight.wlclient.api.WLRequestOptions;

public class WLRequest {

	private WLRequestListener 	requestListener;
	private WLAuthListener 		authListener;
	private HttpPost 			postRequest; 
	private HttpContext 		httpContext;
	private WLRequestOptions 	requestOptions;
	private WLConfig 			config;
	private final static ExecutorService pool = Executors.newFixedThreadPool(6);
	
	public WLRequest(
			WLRequestListener wlRequestListener,
			HttpContext httpContext, 
			WLRequestOptions wlRequestData,
			WLConfig wlConfig) {
		this.requestListener 	= wlRequestListener;
		this.httpContext 		= httpContext;
		this.requestOptions 	= wlRequestData;
		this.config 			= wlConfig;
	}

	/**
	 * Create http request and send it for asynchronous execution
	 * @param requestPath - the request path (for example: init,query etc...)
	 * @param requestOptions - the request options (timeout, user parameters) 
	 * @param config - The config contains the user settings like host, port, version
	 * @param httpClient - the http client object used for invoking the request
	 * @param httpContext - HttpContect object for invoking the request.
	 */
	public void makeRequest(String requestPath) {
		String requestURL = config.getRootURL().toExternalForm() + requestPath; 
		postRequest = new HttpPost(requestURL);
		addHeaders(config, postRequest);
		addParams(requestOptions, postRequest);
		pool.execute(new AsynchronousRequestSender(this));
	}

	private void addHeaders(WLConfig config, HttpPost postRequest) {
		postRequest.addHeader("X-Requested-With", "XMLHttpRequest");
		postRequest.addHeader(WLConfig.WL_DOUBLE_COOKIE_HEADER, config.getApplicationVersion());
		Header cookieHeader = WLCookieManager.createCookieHeader();
		postRequest.addHeader(cookieHeader);
	}

	private void addParams(WLRequestOptions requestOptions, HttpPost postRequest) {
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		if (requestOptions.getParameters() != null && !requestOptions.getParameters().isEmpty()) {
			for (String paramName : requestOptions.getParameters().keySet()) {
				params.add(new BasicNameValuePair(paramName, requestOptions.getParameters().get(paramName)));
			}
		}
		params.add(new BasicNameValuePair("isAjaxRequest", "true"));
		UrlEncodedFormEntity encodedFormEntity = null;
		
		try {
			encodedFormEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
		} catch (UnsupportedEncodingException e) {
			WLClientUtils.error(e.getMessage() ,e);
			throw new RuntimeException (e);
		}
		postRequest.setEntity(encodedFormEntity);
	}
	
	public WLAuthListener getAuthListener() {
		return authListener;
	}

	public void setAuthListener(WLAuthListener authListener) {
		this.authListener = authListener;
	}

	public WLRequestListener getRequestListener() {
		return requestListener;
	}

	public HttpPost getPostRequest() {
		return postRequest;
	}

	public HttpContext getHttpContext() {
		return httpContext;
	}

	public WLRequestOptions getOptions() {
		return requestOptions;
	}

	public WLConfig getConfig() {
		return config;
	}
}
